home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Peter Lewis / FMenus Example / PNL Libraries / MyFMenus.unit next >
Encoding:
Text File  |  1992-11-24  |  6.8 KB  |  290 lines  |  [TEXT/PJMM]

  1. unit MyFMenus;
  2.  
  3. { From Peter's PNL Libraries }
  4. { Copyright 1992 Peter N Lewis }
  5. { This source may be used for any non-commercial purposes as long as I get a mention }
  6. { in the About box and Docs of any derivative program.  It may not be used in any commercial }
  7. { application without my permission }
  8.  
  9. interface
  10.  
  11.     procedure InitFMenus (default: procptr);
  12. { procedure default(themenu,theitem:integer) }
  13. { Call this once at the start of the application, before all the others }
  14.     procedure FinishFMenus;
  15. { Call this ones as the application quits }
  16.  
  17.     function GetFMenu (id: integer): MenuHandle;
  18. { Call this in place of GetMenu, to read in an fmnu resource.  Use InsertMenu to add it to the menu bar }
  19.     procedure SetFCommand (command: OSType; cmdproc: procptr);
  20. { procedure cmdproc }
  21. { Call this to associate a procedure with a command OSType }
  22.     procedure SetFSetMenu (command: OSType; smproc: procptr);
  23. { procedure smproc(themenu,theitem:integer) }
  24. { Call this to associate a procedure for enabling/disabling the menu item }
  25.     procedure SetFBoth (command: OSType; cmdproc, smproc: procptr);
  26. { This is just a short form to set both the command and SetMenu procedures }
  27.  
  28.     procedure SetFMenus;
  29. { Call this before MenuKey or MenuSelect to set the enables of all the menus }
  30.     procedure DoFMenu (themenu, theitem: integer);
  31. { Call this to act on a menu selection from either MenuSelect or MenuKey }
  32.  
  33. { You probably won't need these }
  34.     procedure AddFCommand (themenu, theitem: integer; command: OSType);
  35. { Call this to associate a menu item with an OSType - normally done by GetFMenu }
  36.     procedure GetCommand (themenu, theitem: integer; var command: OSType);
  37. { Call this to figure out what command OSType is associated with a menu item - normally done via DoFMenu }
  38.     procedure DoCommand (themenu, theitem: integer; command: OSType);
  39. { Call this to execute a menu command - normally done via DoFMenu }
  40.  
  41. implementation
  42.  
  43.     uses
  44.         BaseGlobals;
  45. { import the quitNow variable - this is only used for cosmetic reasons, so that }
  46. { the File menu stays highlighted until the application quits }
  47. { Don't forget that you need to turn on the "Uses" Extensions in the Compile Options }
  48.  
  49.     procedure DoSMP (themenu, theitem: integer; smp: procptr);
  50.     inline
  51.         $205F, $4E90;
  52.  
  53.     procedure DoDefCMDP (themenu, theitem: integer; cmdp: procptr);
  54.     inline
  55.         $205F, $4E90;
  56.  
  57.     procedure DoCMDP (cmdp: procptr);
  58.     inline
  59.         $205F, $4E90;
  60.  
  61.     type
  62.         fmenuHeader = record
  63.                 visible: integer;
  64.                 count: integer;
  65.                 unknown1: integer;
  66.                 menuID: integer;
  67.                 unknown2: integer;
  68.                 unknown3: integer;
  69.                 name: str63;
  70.             end;
  71.         fmenuHeaderPtr = ^fmenuHeader;
  72.         fmenuItem = packed record
  73.                 command: OSType;
  74.                 mark: char;
  75.                 unknown2: byte;
  76.                 cmdKey: char;
  77.                 disabled: byte;
  78.                 name: str63;
  79.             end;
  80.         fmenuItemPtr = ^fmenuItem;
  81.         convertRecord = record
  82.                 menu, item: integer;
  83.                 cmd: OSType;
  84.                 cmdp, smp: procptr;
  85.             end;
  86.         convertArray = array[1..1000] of convertRecord;
  87.         convertPtr = ^convertArray;
  88.         convertHandle = ^convertPtr;
  89.  
  90.     var
  91.         defaultproc: procptr;
  92.         convert_count: integer;
  93.         converts: convertHandle;
  94.  
  95. {$S Init}
  96.     procedure InitFMenus (default: procptr);
  97. { procedure default(themenu,theitem:integer) }
  98.     begin
  99.         defaultproc := default;
  100.         convert_count := 0;
  101.         converts := convertHandle(NewHandle(0));
  102.     end;
  103.  
  104. {$S Term}
  105.     procedure FinishFMenus;
  106.     begin
  107.         DisposHandle(handle(converts));
  108.     end;
  109.  
  110. {$S Init}
  111.     procedure AddFCommand (themenu, theitem: integer; command: OSType);
  112.     begin
  113.         if BAND(convert_count, 7) = 0 then
  114.             SetHandleSize(handle(converts), (convert_count + 8) * SizeOf(convertRecord));
  115.         convert_count := convert_count + 1;
  116.         with converts^^[convert_count] do begin
  117.             menu := themenu;
  118.             item := theitem;
  119.             cmd := command;
  120.             cmdp := defaultproc;
  121.             smp := nil;
  122.         end;
  123.     end;
  124.  
  125. {$S Init}
  126.     procedure NextPtr (var p: univ ptr; sp: univ ptr);
  127.     begin
  128.         p := ptr(longInt(sp) + sp^ + 2 - ord(odd(sp^)));
  129.     end;
  130.  
  131. {$S Init}
  132.     function GetFMenu (id: integer): MenuHandle;
  133.         var
  134.             h: handle;
  135.             mh: menuHandle;
  136.             ph: fmenuHeaderPtr;
  137.             p: fmenuItemPtr;
  138.             s: string[70];
  139.             i: integer;
  140.     begin
  141.         h := GetResource('fmnu', id);
  142.         HLock(h);
  143.         ph := fmenuHeaderPtr(h^);
  144.         mh := NewMenu(ph^.menuID, ph^.name);
  145.         NextPtr(p, @ph^.name);
  146.         for i := 1 to ph^.count do begin
  147.             if p^.name = '-' then
  148.                 AppendMenu(mh, '(-')
  149.             else begin
  150.                 AddFCommand(ph^.menuID, i, p^.command);
  151.                 s := p^.name;
  152.                 if p^.mark <> chr(0) then
  153.                     s := concat(s, '!', p^.mark);
  154.                 if p^.cmdKey <> chr(0) then
  155.                     s := concat(s, '/', p^.cmdKey);
  156.                 if p^.disabled = 1 then
  157.                     s := concat('(', s);
  158.                 AppendMenu(mh, s);
  159.             end;
  160.             NextPtr(p, @p^.name);
  161.         end;
  162.         ReleaseResource(h);
  163.         GetFMenu := mh;
  164.     end;
  165.  
  166. {$S}
  167.     procedure FindCommand (command: OSType; var cmdproc: procptr);
  168.         var
  169.             i: integer;
  170.     begin
  171.         i := 1;
  172.         while i <= convert_count do begin
  173.             with converts^^[i] do
  174.                 if cmd = command then begin
  175.                     cmdproc := cmdp;
  176.                     Exit(FindCommand);
  177.                 end;
  178.             i := i + 1;
  179.         end;
  180.         cmdproc := defaultproc;
  181.     end;
  182.  
  183. {$S}
  184.     procedure FindMenu (themenu, theitem: integer; var i: integer);
  185.     begin
  186.         i := 1;
  187.         while i <= convert_count do begin
  188.             with converts^^[i] do
  189.                 if (menu = themenu) and (item = theitem) then
  190.                     Exit(FindMenu);
  191.             i := i + 1;
  192.         end;
  193.         i := -1;
  194.     end;
  195.  
  196. {$S Init}
  197.     procedure SetFCommand (command: OSType; cmdproc: procptr);
  198. { procedure cmdproc }
  199.         var
  200.             i: integer;
  201.     begin
  202.         for i := 1 to convert_count do
  203.             with converts^^[i] do
  204.                 if cmd = command then
  205.                     cmdp := cmdproc;
  206.     end;
  207.  
  208. {$S Init}
  209.     procedure SetFSetMenu (command: OSType; smproc: procptr);
  210. { procedure smproc }
  211.         var
  212.             i: integer;
  213.     begin
  214.         for i := 1 to convert_count do
  215.             with converts^^[i] do
  216.                 if cmd = command then
  217.                     smp := smproc;
  218.     end;
  219.  
  220. {$S Init}
  221.     procedure SetFBoth (command: OSType; cmdproc, smproc: procptr);
  222. { procedure smproc }
  223.         var
  224.             i: integer;
  225.     begin
  226.         for i := 1 to convert_count do
  227.             with converts^^[i] do
  228.                 if cmd = command then begin
  229.                     cmdp := cmdproc;
  230.                     smp := smproc;
  231.                 end;
  232.     end;
  233.  
  234. {$S}
  235.     procedure GetCommand (themenu, theitem: integer; var command: OSType);
  236.         var
  237.             i: integer;
  238.     begin
  239.         FindMenu(themenu, theitem, i);
  240.         if i = -1 then
  241.             command := 'xxx0'
  242.         else
  243.             command := converts^^[i].cmd;
  244.     end;
  245.  
  246. {$S}
  247.     procedure DoCmd (themenu, theitem: integer; cmdp: procptr);
  248.     begin
  249.         if cmdp = defaultproc then
  250.             DoDefCMDP(themenu, theitem, cmdp)
  251.         else
  252.             DoCMDP(cmdp);
  253.     end;
  254.  
  255. {$S}
  256.     procedure DoCommand (themenu, theitem: integer; command: OSType);
  257.         var
  258.             cmdproc: procptr;
  259.     begin
  260.         FindCommand(command, cmdproc);
  261.         DoCmd(themenu, theitem, cmdproc);
  262.     end;
  263.  
  264. {$S}
  265.     procedure DoFMenu (themenu, theitem: integer);
  266.         var
  267.             i: integer;
  268.     begin
  269.         FindMenu(themenu, theitem, i);
  270.         if i = -1 then
  271.             DoCmd(themenu, theitem, defaultproc)
  272.         else
  273.             with converts^^[i] do
  274.                 DoCmd(themenu, theitem, cmdp);
  275.         if not quitNow then
  276.             HiliteMenu(0);
  277.     end;
  278.  
  279. {$S}
  280.     procedure SetFMenus;
  281.         var
  282.             i: integer;
  283.     begin
  284.         for i := 1 to convert_count do
  285.             with converts^^[i] do
  286.                 if smp <> nil then
  287.                     DoSMP(menu, item, smp);
  288.     end;
  289.  
  290. end.